package io.gitee.zhangbinhub.admin.controller.api

import cn.dev33.satoken.annotation.SaCheckPermission
import cn.dev33.satoken.stp.StpUtil
import io.gitee.zhangbinhub.acp.boot.exceptions.WebException
import io.gitee.zhangbinhub.acp.boot.log.LogAdapter
import io.gitee.zhangbinhub.acp.core.common.CommonTools
import io.gitee.zhangbinhub.admin.api.ServerApi
import io.gitee.zhangbinhub.admin.base.BaseController
import io.gitee.zhangbinhub.admin.constant.ModuleFuncCode
import io.gitee.zhangbinhub.admin.constant.RoleCode
import io.gitee.zhangbinhub.admin.entity.Role
import io.gitee.zhangbinhub.admin.po.RolePo
import io.gitee.zhangbinhub.admin.service.RoleService
import io.gitee.zhangbinhub.admin.vo.InfoVo
import io.gitee.zhangbinhub.admin.vo.RoleVo
import io.swagger.annotations.Api
import io.swagger.annotations.ApiOperation
import io.swagger.annotations.ApiParam
import org.noear.solon.annotation.*
import org.noear.solon.core.handle.MethodType
import org.noear.solon.core.util.MimeType
import org.noear.solon.validation.annotation.NotEmpty
import org.noear.solon.validation.annotation.NotNull
import org.noear.solon.validation.annotation.Valid
import org.noear.solon.validation.annotation.Validated

@Valid
@Controller
@Api("角色信息")
open class RoleController(
    private val logAdapter: LogAdapter,
    private val roleService: RoleService
) : BaseController(logAdapter) {

    private val roleCodeList: MutableList<String> = mutableListOf()

    @ApiOperation("获取角色编码列表")
    @SaCheckPermission(ModuleFuncCode.roleConfig, orRole = [RoleCode.SUPER])
    @Mapping(
        method = [MethodType.GET],
        value = ServerApi.basePath + ServerApi.roleCodes,
        produces = MimeType.APPLICATION_JSON_VALUE
    )
    fun findRoleCode(): List<String> = roleCodeList

    @Init
    fun init() {
        try {
            for (field in RoleCode::class.java.declaredFields) {
                val value = field.get(RoleCode::class.java)
                if (value is String) {
                    roleCodeList.add(value)
                }
            }
            roleCodeList.sort()
        } catch (e: Exception) {
            logAdapter.error(e.message, e)
        }
    }

    @ApiOperation("获取指定应用下可编辑的角色列表", notes = "查询指定应用下可编辑的角色列表")
    @SaCheckPermission(ModuleFuncCode.roleConfig, orRole = [RoleCode.SUPER])
    @Mapping(
        method = [MethodType.GET],
        value = ServerApi.basePath + ServerApi.roleList + "/{appId}",
        produces = MimeType.APPLICATION_JSON_VALUE
    )
    @Throws(WebException::class)
    fun getRoleList(@Path(name = "appId") appId: String): List<Role> =
        roleService.getRoleListByAppId(StpUtil.getLoginIdAsString(), appId)

    @ApiOperation("获取角色列表", notes = "查询所有角色列表")
    @SaCheckPermission(ModuleFuncCode.roleQuery, orRole = [RoleCode.SUPER])
    @Mapping(
        method = [MethodType.GET],
        value = ServerApi.basePath + ServerApi.roleConfig,
        produces = MimeType.APPLICATION_JSON_VALUE
    )
    @Throws(WebException::class)
    fun roleList(): List<Role> = roleService.getRoleList()

    @ApiOperation("新建角色信息", notes = "名称、编码、应用ID、级别、序号、关联用户、关联菜单、关联模块功能")
    @SaCheckPermission(ModuleFuncCode.roleAdd, orRole = [RoleCode.SUPER])
    @Mapping(
        method = [MethodType.PUT],
        value = ServerApi.basePath + ServerApi.roleConfig,
        produces = MimeType.APPLICATION_JSON_VALUE
    )
    @Throws(WebException::class)
    fun add(@Body @Validated rolePo: RolePo): Role {
        if (CommonTools.isNullStr(rolePo.appId)) {
            throw WebException("应用ID不能为空")
        }
        return roleService.doCreate(StpUtil.getLoginIdAsString(), rolePo)
    }

    @ApiOperation("删除指定的角色信息")
    @SaCheckPermission(ModuleFuncCode.roleDelete, orRole = [RoleCode.SUPER])
    @Mapping(
        method = [MethodType.DELETE],
        value = ServerApi.basePath + ServerApi.roleConfig,
        produces = MimeType.APPLICATION_JSON_VALUE
    )
    @Throws(WebException::class)
    fun delete(
        @ApiParam("id列表", required = true)
        @NotEmpty(message = "id不能为空")
        @NotNull(message = "id不能为空")
        @Body
        idList: MutableList<String>
    ): InfoVo = roleService.doDelete(StpUtil.getLoginIdAsString(), idList).let { InfoVo(message = "删除成功") }

    @ApiOperation("更新角色信息", notes = "名称、编码、级别、序号、关联用户、关联菜单、关联模块功能")
    @SaCheckPermission(ModuleFuncCode.roleUpdate, orRole = [RoleCode.SUPER])
    @Mapping(
        method = [MethodType.PATCH],
        value = ServerApi.basePath + ServerApi.roleConfig,
        produces = MimeType.APPLICATION_JSON_VALUE
    )
    @Throws(WebException::class)
    fun update(@Body @Validated rolePo: RolePo): Role {
        if (CommonTools.isNullStr(rolePo.id)) {
            throw WebException("ID不能为空")
        }
        return roleService.doUpdate(StpUtil.getLoginIdAsString(), rolePo)
    }

    @ApiOperation("获取角色详细信息")
    @SaCheckPermission(ModuleFuncCode.roleQuery, orRole = [RoleCode.SUPER])
    @Mapping(
        method = [MethodType.GET],
        value = ServerApi.basePath + ServerApi.roleConfig + "/{roleId}",
        produces = MimeType.APPLICATION_JSON_VALUE
    )
    @Throws(WebException::class)
    fun roleInfo(@Path(name = "roleId") roleId: String): RoleVo = roleService.getRoleInfo(roleId)

}
